<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import {
  $getSelection,
  $isRangeSelection,
  $createTextNode,
  $isTextNode,
  $isParagraphNode,
  $createParagraphNode
} from 'lexical'
import { useLexicalComposer } from 'lexical-vue'
import { $createVariableNode } from '@/views/LLMStudio/build/components/prompt-editor/variable-block/node'

const editor = useLexicalComposer()
const showSuggestions = ref(false)
const suggestions = ref([
  { icon: '👤', name: 'name' },
  { icon: '📧', name: 'email' },
  { icon: '📞', name: 'phone' },
  { icon: '🏠', name: 'address' }
])
const selectedIndex = ref(0)
const anchorElem = ref(null)

function handleKeyDown(event) {
  if (!showSuggestions.value) return
  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault()
      selectedIndex.value = (selectedIndex.value + 1) % suggestions.value.length
      break
    case 'ArrowUp':
      event.preventDefault()
      selectedIndex.value =
        (selectedIndex.value - 1 + suggestions.value.length) % suggestions.value.length
      break
    case 'Enter':
      event.preventDefault()
      event.stopPropagation()
      insertVariable(suggestions.value[selectedIndex.value].name)
      break
    case 'Escape':
      event.preventDefault()
      showSuggestions.value = false
      break
  }
}

function insertVariable(variable) {
  editor.update(() => {
    const selection = $getSelection()
    if ($isRangeSelection(selection)) {
      const anchorNode = selection.anchor.getNode()
      if ($isTextNode(anchorNode)) {
        const textContent = anchorNode.getTextContent()
        const cursorPosition = selection.anchor.offset

        // 移除触发字符 "{"
        const newTextBefore = textContent.slice(0, cursorPosition - 1)
        const newTextAfter = textContent.slice(cursorPosition)

        // 创建新的文本节点和变量节点
        const newTextNodeBefore = $createTextNode(newTextBefore)
        const newTextNodeAfter = $createTextNode(newTextAfter)
        const variableNode = $createVariableNode(variable)

        // 获取或创建段落节点
        let paragraphNode = anchorNode.getParentOrThrow()
        if (!$isParagraphNode(paragraphNode)) {
          paragraphNode = $createParagraphNode()
          paragraphNode.append(anchorNode)
          anchorNode.getParentOrThrow().replace(paragraphNode)
        }

        // 替换当前节点
        anchorNode.remove()
        paragraphNode.append(newTextNodeBefore, variableNode, newTextNodeAfter)

        // 将选择移动到变量节点之后
        newTextNodeAfter.select(0, 0)
      }
    }
    showSuggestions.value = false
  })
}

function checkForTrigger() {
  editor.update(() => {
    const selection = $getSelection()
    if ($isRangeSelection(selection)) {
      const anchorNode = selection.anchor.getNode()
      if ($isTextNode(anchorNode)) {
        const textContent = anchorNode.getTextContent()
        const cursorPosition = selection.anchor.offset
        if (cursorPosition > 0 && textContent[cursorPosition - 1] === '{') {
          showSuggestions.value = true
          setTimeout(updateSuggestionPosition, 5)
        } else {
          showSuggestions.value = false
        }
      } else {
        showSuggestions.value = false
      }
    } else {
      showSuggestions.value = false
    }
  })
}

function updateSuggestionPosition() {
  editor.getEditorState().read(() => {
    const selection = $getSelection()
    if ($isRangeSelection(selection)) {
      const anchorNode = selection.anchor.getNode()
      const domElement = editor.getElementByKey(anchorNode.getKey())
      if (domElement && anchorElem.value) {
        const rect = domElement.getBoundingClientRect()
        anchorElem.value.style.top = `${rect.bottom}px`
        anchorElem.value.style.left = `${rect.left}px`
        anchorElem.value.style.display = 'block'
      }
    }
  })
}

onMounted(() => {
  editor.registerUpdateListener(({ editorState }) => {
    editorState.read(() => {
      checkForTrigger()
    })
  })
  document.addEventListener('keydown', handleKeyDown, true)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown, true)
})
</script>

<template>
  <div ref="anchorElem" v-if="showSuggestions" class="suggestions-menu">
    <ul>
      <li
        v-for="(suggestion, index) in suggestions"
        :key="suggestion.name"
        :class="{ active: index === selectedIndex }"
        @click="insertVariable(suggestion.name)"
      >
        <span class="icon">{{ suggestion.icon }}</span>
        <span class="name">{{ suggestion.name }}</span>
      </li>
    </ul>
  </div>
</template>

<style scoped>
.suggestions-menu {
  position: fixed;
  display: none;
  background: white;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  z-index: 1000;
  min-width: 200px;
}

.suggestions-menu ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.suggestions-menu li {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: background-color 0.2s ease;
}

.suggestions-menu li:hover,
.suggestions-menu li.active {
  background-color: #f0f5ff;
}

.suggestions-menu li .icon {
  margin-right: 8px;
  font-size: 1.2em;
}

.suggestions-menu li .name {
  font-size: 0.9em;
}
</style>
